在本系列文中,所有的程式碼以及測試都可以在 should-i-use-fp-ts 找到,今日的範例放在 src/day-05
並且有習題和測試可以讓大家練習。
Point-free style — aims to reduce some of the visual clutter by removing unnecessary parameter-argument mapping."
- Kyle Simpson
pointfree
是 functional programming
中的一種特性,也可以稱為 tacit (無參數) programming
。pointfree
的概念是在特定情況下函數使用不需要標注參數(點 point
),這個特性在之後的程式常常使用到,有助於讓我們的程式更加的簡潔,專注於如何宣告我們的結果。
先來一段簡單的範例吧,這邊使用 array 的 function 來示範,將 list 中的所有元素都加一,然後把所有的數字都改成字串。
const list = [1, 2, 3, 4, 5];
# point style
list.map(x => x + 1)
.map(x => x.toString()); // ['2', '3', '4', '5', '6']
# pointfree
const inc = (x: number) => x + 1;
const toString = (x: number) => x.toString();
list.map(inc)
.map(toString); // ['2', '3', '4', '5', '6']
或許有些讀者會有疑問,原本兩行的程式平白變成四行了,這樣是不是 pointfree
反而讓程式變繁複了?
inc
, toString
並不是只用在這裡,他可以廣泛的應用在程式的其他部分。pointfree
的部分,可以發現這邊更加的語意化,可以將意圖直接敘述出來,這樣可以隱藏不需要的細節,專注在目前的邏輯上。list
map
所有元素都進行一次 inc
)。再來說明一下使用 pointfree
的注意事項,如果 pointfree
使用的函數是可以接受多參數的時候,可能會有效果不符預期的情況,一樣使用 array 的 function 來示範。
const list = [1, 2, 3, 4, 5];
list.map(inc)
.map(toString) // ['2', '3', '4', '5', '6']
.map(console.log)
// output:
/* '2', 0, ['2', '3', '4', '5', '6']
* '3', 1, ['2', '3', '4', '5', '6']
* '4', 2, ['2', '3', '4', '5', '6']
* '5', 3, ['2', '3', '4', '5', '6']
* '6', 4, ['2', '3', '4', '5', '6']
*/
會有這樣的結果是由於 console.log
本身接收的參數是 (...data: any[])
,而 pointfree
會接收所有 callback
傳過來的函數(ex. map => (value, index, array)
),使用上有這點需要稍微注意一下。
今天的主題在 should-i-use-fp-ts 在 src/day-05
並且有習題和測試可以讓大家練習。
聊一聊函数式编程中的pointfree
Pointfree 编程风格指南 - 阮一峰大神寫的,強烈推薦。